package interceptors;

import com.alibaba.fastjson.JSONObject;
import common.ThreadLocalManager;
import dao.UserMapper;
import entity.User;
import enums.LoginEnum;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import utils.CookieUtil;
import utils.DateUtil;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Writer;
import java.util.Date;

/**
 * 登录拦截器
 * Created by weijianyu on 2017/4/10.
 */
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger logger = LogManager.getLogger(LoginInterceptor.class);

    private final UserMapper userMapper;

    /**
     * LoginInterceptor 构造函数
     * 初始化
     *
     * @param userMapper userMapper 服务
     */
    @Autowired
    public LoginInterceptor(UserMapper userMapper) {
        Assert.notNull(userMapper, "userMapper must nut null");
        this.userMapper = userMapper;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        JSONObject error = new JSONObject();

        Cookie[] cookies = request.getCookies();
        if (cookies == null || cookies.length <= 0) {
            logger.info("拦截器 cookie未传");

            error.put("code", LoginEnum.ERROR_COOKIE_NULL.getCode());
            error.put("message", LoginEnum.ERROR_COOKIE_NULL.getMessage());
            response.setContentType("application/json;charset=UTF-8");
            Writer writer = response.getWriter();
            writer.write(error.toJSONString());
            return false;
        }
        for (Cookie cookie : cookies) {
            if ("isid".equals(cookie.getName())) {
                String isid = cookie.getValue();
                String cookieInfo = CookieUtil.desDecryption(isid);

                if ("".equals(cookieInfo)) {
                    logger.info("cookie失效");

                    error.put("code", LoginEnum.ERROR_COOKIE_FAILURE.getCode());
                    error.put("message", LoginEnum.ERROR_COOKIE_FAILURE.getMessage());
                    response.setContentType("application/json;charset=UTF-8");
                    Writer writer = response.getWriter();
                    writer.write(error.toJSONString());
                    return false;
                }

                if (!CookieUtil.cookieSalt().equals(CookieUtil.getSalt(cookieInfo))) {
                    logger.warn("拦截器 cookie:{} 信息仿造", cookieInfo);

                    error.put("code", LoginEnum.ERROR_COOKIE_IMITATION.getCode());
                    error.put("message", LoginEnum.ERROR_COOKIE_IMITATION.getMessage());
                    response.setContentType("application/json;charset=UTF-8");
                    Writer writer = response.getWriter();
                    writer.write(error.toJSONString());
                    return false;
                }

                String effectiveDate = CookieUtil.getEffectiveDate(cookieInfo);
                if (new Date().getTime() >
                        DateUtil.string2Date(effectiveDate, DateUtil.TOSECOND).getTime()) {
                    logger.info("拦截器 cookie过期需要重新登录");

                    error.put("code", LoginEnum.ERROR_COOKIE_TIMEOUT.getCode());
                    error.put("message", LoginEnum.ERROR_COOKIE_TIMEOUT.getMessage());
                    response.setContentType("application/json;charset=UTF-8");
                    Writer writer = response.getWriter();
                    writer.write(error.toJSONString());
                    return false;
                }

                int userId = CookieUtil.getUserId(cookieInfo);
                User user = userMapper.selectByPrimaryKey(userId);
                if (user != null) {
                    ThreadLocalManager.setUserSession(user);
                }
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        ThreadLocalManager.clear();
    }
}
